package com.sztx.pay.center.rpc.service;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.sztx.pay.center.common.annotation.SlaveQueryAnnotation;
import com.sztx.pay.center.common.util.DateUtil;
import com.sztx.pay.center.core.service.ActService;
import com.sztx.pay.center.dataaccess.dao.mysql.UserActBalanceChangeMysqlDAO;
import com.sztx.pay.center.dataaccess.dao.mysql.UserActFlowMysqlDAO;
import com.sztx.pay.center.dataaccess.dao.mysql.UserActMysqlDAO;
import com.sztx.pay.center.dataaccess.domain.UserActBalanceChangeDO;
import com.sztx.pay.center.dataaccess.domain.UserActDO;
import com.sztx.pay.center.dataaccess.domain.UserActFlowDO;
import com.sztx.pay.center.rpc.api.service.UserActChangeRpcService;
import com.sztx.se.core.service.impl.BaseServiceImpl;

@Service
public class UserActChangeRpcServiceImpl extends BaseServiceImpl implements UserActChangeRpcService {

	@Autowired
	private UserActMysqlDAO userActMysqlDAO;
	
	@Autowired
	private UserActFlowMysqlDAO userActFlowMysqlDAO;
	
	@Autowired
	private UserActBalanceChangeMysqlDAO userActBalanceChangeMysqlDAO;

	@Autowired
	private ActService actService;
	
	
	@Override
	@Async
	public void statisticsBalanceChange() {
		
		
		Date today = new Date();
		Date beforeDate = getBeforeDate(today, 1);
		Date beforeYesterDay = getBeforeDate(today, 2);
		//查询前昨天有没有数据,有则认为已经执行过
		UserActBalanceChangeDO yesterDayDO = new UserActBalanceChangeDO();
		yesterDayDO.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
		List<UserActBalanceChangeDO> yesterDayDOs = userActBalanceChangeMysqlDAO.listPage(yesterDayDO , null);
		if (!CollectionUtils.isEmpty(yesterDayDOs)) {
			LOG.info("已执行一次,不重复执行");
			return;
		}
		
		
		//查询前天有没有数据,有则认为不是第一次执行
		UserActBalanceChangeDO beforeYesterDayDO = new UserActBalanceChangeDO();
		beforeYesterDayDO.setDay(DateUtil.formatDate(beforeYesterDay, DateUtil.SHORT_DATE_FORMAT_STR));
		List<UserActBalanceChangeDO> listPage = userActBalanceChangeMysqlDAO.listPage(beforeYesterDayDO , null);
		boolean hasData = CollectionUtils.isEmpty(listPage);
		Map<String, Long> actNoAndBalanceMap = new HashMap<>();
		if (hasData) {
			actNoAndBalanceMap = createActNoAndBalanceMap(listPage);
		}
		
		String startTime = DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR) + " 00:00:00";
		String endTime = DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR) + " 23:59:59"; 
		//查询balance_time大于昨天的数据
		List<UserActDO> userActs = userActMysqlDAO.findMaybeChangeUserActs(startTime);
		if (CollectionUtils.isNotEmpty(userActs)) {
			for (UserActDO userActDO : userActs) {
				String actNo = userActDO.getActNo();
				String userId = userActDO.getUserId();
				Integer userType = userActDO.getUserType();
				Integer actType = userActDO.getActType();
				//查询ActFlow不存在则递归查询前一个月内的数据直到查出来为止,minus
				Integer actFlowCountByActNo = userActFlowMysqlDAO.getActFlowCountByActNo(startTime, endTime, userActDO.getActNo());
				if (actFlowCountByActNo == 0) {
					int beforeMonth = 1;
					handleBeforeMonthActFlow(beforeDate, userActDO.getActNo(), beforeMonth, userActDO.getUserType());
					continue;
				} else {
					UserActFlowDO lastActFlowByActNo = userActFlowMysqlDAO.getLastActFlowByActNo(startTime, endTime, actNo);
					long changeBalance = 0L;
					long beforeBalance = 0L;
					if (hasData && actNoAndBalanceMap.containsKey(actNo)) {
						beforeBalance = actNoAndBalanceMap.get(actNo);
					} else {
						UserActFlowDO firstActFlowByActNo = userActFlowMysqlDAO.getFirstActFlowByActNo(startTime, endTime, actNo);
						beforeBalance = firstActFlowByActNo.getActBalance() - firstActFlowByActNo.getTranAmount();
					}
					
					changeBalance = lastActFlowByActNo.getActBalance() - beforeBalance;
					Date lastModifyTime = lastActFlowByActNo.getCreateTime();
					String lastActFlowNo = lastActFlowByActNo.getActFlowNo();
					UserActBalanceChangeDO t = new UserActBalanceChangeDO();
					t.setActNo(actNo);
					t.setActType(actType);
					t.setBalance(lastActFlowByActNo.getActBalance());
					t.setChangeBalance(changeBalance);
					t.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
					t.setLastActFlowNo(lastActFlowNo);
					t.setLastModifyTime(lastModifyTime);
					t.setUserId(userId);
					t.setUserType(userType);
					t.setBeforeBalance(beforeBalance);
					userActBalanceChangeMysqlDAO.save(t);
				}
			}
		}
		
		//查询balance_time小于昨天凌晨的,直接写入数据库记录
		List<UserActDO> hasnotChangeUserActs = userActMysqlDAO.findHasnotChangeUserAct(startTime);
		if (CollectionUtils.isNotEmpty(hasnotChangeUserActs)) {
			for (UserActDO hasnotChangeUserAct : hasnotChangeUserActs) {
				UserActBalanceChangeDO t = new UserActBalanceChangeDO();
				t.setActNo(hasnotChangeUserAct.getActNo());
				t.setActType(hasnotChangeUserAct.getActType());
				t.setBalance(hasnotChangeUserAct.getActBalance());
				t.setChangeBalance(0L);
				t.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
				t.setLastActFlowNo(null);
				t.setLastModifyTime(null);
				t.setUserId(hasnotChangeUserAct.getUserId());
				t.setUserType(hasnotChangeUserAct.getUserType());
				t.setBeforeBalance(hasnotChangeUserAct.getActBalance());
				userActBalanceChangeMysqlDAO.save(t);
			}
		}
		return;
	}
	
	private Map<String, Long> createActNoAndBalanceMap(List<UserActBalanceChangeDO> listPage) {
		Map<String, Long> actNoAndBalanceMap = new HashMap<>();
		for (UserActBalanceChangeDO userActBalanceChangeDO : listPage) {
			actNoAndBalanceMap.put(userActBalanceChangeDO.getActNo(), userActBalanceChangeDO.getBalance());
		}
		return actNoAndBalanceMap;
	}



	private void handleBeforeMonthActFlow(Date beforeDate, String actNo, int beforeMonth, int userType) {
		
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(beforeDate);
		startCalendar.add(Calendar.MONTH, -beforeMonth);// 当前时间前去beforeMonth个月
		Date startDate = startCalendar.getTime();// 
		
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(beforeDate);
		endCalendar.add(Calendar.MONTH, -(beforeMonth - 1));// 当前时间前去beforeMonth个月
		Date endDate = endCalendar.getTime();
		
		UserActFlowDO lastActFlowByActNo = userActFlowMysqlDAO.getLastActFlowByActNo(DateUtil.formatDate(startDate, DateUtil.SHORT_DATE_FORMAT_STR) + " 00:00:00", DateUtil.formatDate(endDate, DateUtil.SHORT_DATE_FORMAT_STR) + " 23:59:59", actNo);
		if (lastActFlowByActNo == null) {
			//查询当天的第一条记录进行返回
			UserActFlowDO todayFirstActFlowByActNo = userActFlowMysqlDAO.getFirstActFlowByActNo(DateUtil.formatDate(new Date(), DateUtil.SHORT_DATE_FORMAT_STR) + " 00:00:00", DateUtil.formatDate(new Date(), DateUtil.SHORT_DATE_FORMAT_STR) + " 23:59:59", actNo);
			
			if (todayFirstActFlowByActNo == null) {
				UserActDO findUserAct = actService.findUserAct(actNo);
				UserActBalanceChangeDO t = new UserActBalanceChangeDO();
				t.setActNo(actNo);
				t.setActType(findUserAct.getActType());
				t.setBalance(findUserAct.getActBalance());
				t.setChangeBalance(0L);
				t.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
				t.setLastActFlowNo(null);
				t.setLastModifyTime(null);
				t.setUserId(findUserAct.getUserId());
				t.setBeforeBalance(findUserAct.getActBalance());
				t.setUserType(userType);
				userActBalanceChangeMysqlDAO.save(t);
				return;
			}
			UserActBalanceChangeDO t = new UserActBalanceChangeDO();
			t.setActNo(actNo);
			t.setActType(todayFirstActFlowByActNo.getActType());
			t.setBalance(todayFirstActFlowByActNo.getActBalance() - todayFirstActFlowByActNo.getTranAmount());
			t.setChangeBalance(0L);
			t.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
			t.setLastActFlowNo(null);
			t.setLastModifyTime(null);
			t.setUserId(todayFirstActFlowByActNo.getUserId());
			t.setBeforeBalance(todayFirstActFlowByActNo.getActBalance() - todayFirstActFlowByActNo.getTranAmount());
			t.setUserType(userType);
			userActBalanceChangeMysqlDAO.save(t);
			return;
		} else {
			UserActBalanceChangeDO t = new UserActBalanceChangeDO();
			t.setActNo(actNo);
			t.setActType(lastActFlowByActNo.getActType());
			t.setBalance(lastActFlowByActNo.getActBalance());
			t.setChangeBalance(0L);
			t.setDay(DateUtil.formatDate(beforeDate, DateUtil.SHORT_DATE_FORMAT_STR));
			t.setLastActFlowNo(null);
			t.setLastModifyTime(null);
			t.setUserId(lastActFlowByActNo.getUserId());
			t.setBeforeBalance(lastActFlowByActNo.getActBalance());
			t.setUserType(userType);
			userActBalanceChangeMysqlDAO.save(t);
			return;
		}
	}



	private Date getBeforeDate(Date date, int beforeDay) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, - beforeDay);

		return c.getTime();
	}

}
